/**
 * @author Gragory Banfi
 * @author Virginie Blancs
 * @author Fatima Chegini
 * @author Nicolas Latorre
 */
package sa4.routing

import javax.servlet.http._
import javax.servlet.ServletConfig
import scala.collection.mutable.HashMap
import scala.io.Codec
import java.io.File

class Routing {
  type HandlerFunction = (HttpServletRequest, HttpServletResponse) => Unit
  val routeTable = new HashMap[String, HandlerFunction]

  /**
   * Function that adds a new route to the routeTable, with an associated handler function
   * @param path The new path to be added to the route
   * @param function The function associated to this new path
   */
  def addRoute(path: String, function: HandlerFunction) {
    routeTable(path) = function
  }

  /**
   * Function that checks if it exists some function in the routeTable
   * @param req Request from the servlet
   * @param resp Response to the servlet
   * @return Boolean True if there exists a function, false otherwise
   */
  def tableDispatch(req: HttpServletRequest, resp: HttpServletResponse): Boolean = {
    routeTable.get(req.getRequestURI) match {
      case Some(f) => f(req, resp); true
      case None =>
        val name_file = req.getRequestURI.split("/")(1)
        if(name_file.endsWith(".css")) {
        	val (uri, f: HandlerFunction) = makeHandler("src/main/scala/sa4/bootstrap/css/"+name_file)		
        	addRoute(uri, f)
        	f(req, resp); true
        }
        else if(name_file.endsWith(".js")) {
          val (uri, f: HandlerFunction) = makeHandler("src/main/scala/sa4/betapp/Javascript/"+name_file)		
        	addRoute(uri, f)
        	f(req, resp); true
        }
        else {
        	false
        } 
    }
  }

  /**
   * Function that parse a header method and creates a new route and install it in the route table with its corresponding handler function.
   * @param s 	a String that represent the header of the method.
   */
  def makeHandler(s: String): (String, HandlerFunction) = {
    val h = (req: HttpServletRequest, resp: HttpServletResponse) => {
      val file = loadFile(s)
      resp.getWriter.write(file)
      val contentType = req.getContentType
      resp.setContentType("text/"+contentType)
    }
    (handlerURI(s), h)
  }

  /**
   * Function that constructs a new route with the method name.
   * @param methodName 	a String that contain the method that will be used as path.
   */
  def handlerURI(methodName: String) = {
    "/" + methodName
  }
  
  /**
   * Function that will load a file from the file system.
   * @param filePath	a String that contain the name of the file.
   * @return			a String that contain all the file.
   */
  def loadFile(filePath: String) = {
    val basePage = scala.io.Source.fromFile(filePath)(Codec.ISO8859).toArray.mkString
    basePage
  }

  /**
   * Function that return the routeTable
   * @return routeTable The routeTable
   */
  def getRouteTable: HashMap[String, HandlerFunction] = return routeTable

  /**
   * Function that remove a specific route from the routeTable
   * @param s A string that represent the route that you want to delete
   */
  def removeRoute(s: String) = routeTable.remove(s)

  /**
   * Function that remove all the mapping routes from the routeTable
   */
  def clearRouteTable = routeTable.clear()
}